/***************************************************************************
 *   Copyright (C) 2005 by ywchen2000                              *
 *   ywchen2000@yahoo.com.cn                                                          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include<iostream>
#include <QListWidget>
#include <QListWidgetItem>
#include"public.h"
using namespace std;
template<class D,class T>                  //jiedian2
class snode
{
 private:
     node<T> *next;
     snode<D,T> *snext;
 public:
     D data;
     snode(void);
     snode(D data1);
void setnode(D data1,node<T> *p);
void insertafter(node<T> *p);
void deleteafter(void);
node<T>* nextnode(void);
//operator snode<D,T>
void sinsertafter(snode<D,T> *p);
void sdeleteafter(void);
snode<D,T>* snextnode(void);
};

//link class D,class T
template<class D,class T>
class mylink
{
  public:
       mylink(void);
      ~mylink(void); 
  bool insert(snode<D,T> *p)throw(error_name);
  bool insert(const D startdata,node<T> *p)throw(error_name);
  bool newdelete(snode<D,T> *p)throw(error_name);                  
  bool newdelete(const D startdata,node<T> *p)throw(error_name);                                
  void print(void); 
  void mat_print(void);
  void athead(void);
  void destroy(void);
  snode<D,T> gethead(void);
  void display_QEdit_Text(QListWidget* e);
  private:
  void deletelink(snode<D,T> *stemppointer);   
      snode<D,T> *shead,*snewnode,*spointer;
      node<T> *head,*newnode,*pointer;                                      
};
template<class D,class T>
snode<D,T>::snode(void)
{
    next=NULL;
    snext=NULL;
}
/*
template<class D,class T>
snode<D,T>::snode(D data1,node<T> *p=NULL)
{
   data=data1;
   next=p;
}
  */
template<class D,class T>
snode<D,T>::snode(D data1)
{
   data=data1;
   next=NULL;
   snext=NULL;
}

template<class D,class T>
void snode<D,T>::setnode(D data1,node<T> *p=NULL)  // snode x------->node p
{
         data=data1;
	 next=p;
}

template<class D,class T>             //operator class node<T> *p;
void snode<D,T>::insertafter(node<T> *p)
{
       next=p;
}
template<class D,class T>
void snode<D,T>::deleteafter(void)
{
      node<T> *temp;
      temp=next;
      next=temp->next;
      delete temp;
}
template<class D,class T>
node<T>* snode<D,T>::nextnode(void)
{
	return next;
}
template<class D,class T>           //operator class snode<D,T>
void snode<D,T>::sinsertafter(snode<D,T> *p)
{
      snext=p;
}
template<class D,class T>
void snode<D,T>::sdeleteafter(void)
{
      snode<D,T> *temp;
      temp=snext;
      snext=temp->snext;
      delete temp;
}
template<class D,class T>
snode<D,T>* snode<D,T>::snextnode(void)
{
       return snext;
}
/////////////////////////////////////////////////////////
template<class D,class T>
mylink<D,T>::mylink(void)
{
    shead=NULL;
    snewnode=NULL;
    spointer=NULL;
    head=NULL;
    newnode=NULL;
    pointer=NULL;
}
template<class D,class T>
mylink<D,T>::~mylink(void)
{
     snode<D,T> *stemp;
     if(shead!=NULL)
         {
           while(shead!=NULL)
              {
                stemp=shead;
                deletelink(stemp);
                shead=shead->snextnode();
                delete stemp;
     //           cout<<"stemp:"<<stemp->data<<endl;
              }   
          }
}
template<class D,class T>
void mylink<D,T>::destroy(void)
{
     snode<D,T> *stemp;
     if(shead!=NULL)
         {
           while(shead!=NULL)
              {
                stemp=shead;
                deletelink(stemp);
                shead=shead->snextnode();
                delete stemp;
     //           cout<<"stemp:"<<stemp->data<<endl;
              }   
          }
}
template<class D,class T>
void mylink<D,T>::deletelink(snode<D,T> *stemppointer)
{
              node<T> *temp;
              node<T> *temppointer; 
         temppointer=stemppointer->nextnode();
         while(temppointer!=NULL)
             {
              temp=temppointer;
              temppointer=temppointer->nextnode();
              delete temp;
    //           cout<<"temppointer"<<temppointer->data<<endl;
               }
}
template<class D,class T>
bool mylink<D,T>::insert(snode<D,T> *p)throw(error_name)
{
  if(p==NULL)
   {
         throw new error_name("node will be inserted is empty");
     }
  if(shead==NULL)
   {
         shead=p;
        }
  else
   {
    /* spointer=shead;
     while(spointer->snextnode()!=NULL)
          {
            spointer=spointer->snextnode();
             }
         
     p->sinsertafter(spointer->snextnode());
     spointer->sinsertafter(p);
      */
     p->sinsertafter(shead);
     shead=p;
     return true;
     }          
}
template<class D,class T>
bool mylink<D,T>::insert(const D startdata,node<T> *p)throw(error_name)
{
   if(p==NULL) 
         {
       throw new error_name("node will be inserted is empty");
          }
    spointer=shead;
    while(spointer!=NULL)
        {
           if(spointer->data==startdata)
                 {
                   pointer=spointer->nextnode();
                       if(pointer==NULL)
                           {
                          spointer->insertafter(p);
			  return true;
                           }
                  /*
                      while(pointer->nextnode()!=NULL)
                           {
                              pointer=pointer->nextnode();
                           }
                */
                              p->insert(pointer->nextnode());
                              pointer->insert(p);
                              return true;
                      }     
            spointer=spointer->snextnode();
          }                        
     return false;
}
template<class D,class T>
bool mylink<D,T>::newdelete(snode<D,T> *p) throw(error_name)
{
     snode<D,T> *stemp=NULL,*spre=NULL;
      node<T> *temp=NULL;
     if(shead==NULL) throw new error_name("no data in shead");
     if(shead==p)
       {
         spointer=shead;
         shead=shead->snextnode();
         deletelink(spointer);
         return true;
       }
     else
       {
           spointer=shead;
           while(spointer!=NULL)
            {
                spre=spointer;                  
                spointer=spointer->snextnode();
                if(spointer==p)
                     {
                   stemp=spointer->snextnode();
                   deletelink(spointer);
                   spre->sinsertafter(stemp);
                   spointer=spre->snextnode();
                   return true;                                          
                        }
            }
        }
}
template<class D,class T>
bool mylink<D,T>::newdelete(const D strartdata,node<T> *p)throw(error_name)
{
        node<T> *pre,*temp;
        spointer=shead;
        if(shead==NULL)
           {
               throw new error_name("head of node is empty");
                  }
        while(spointer!=NULL)
          {
            if(spointer->data==strartdata)
                  {
                     pointer=spointer->nextnode();
                     if(pointer==NULL)
                        {
                           return false;
                         }
                     if(pointer==p)
                        {
                        temp=pointer->nextnode();
                        spointer->insertafter(temp);
                        delete pointer;
                        return true;
                          }
                     else
                       {
                         while(pointer!=NULL)
                            {
                               pre=pointer;
                               pointer=pointer->nextnode();
                               if(pointer==p)
                                 {
                                   pre->deleteafter();
                                   pointer=pre->nextnode();   
                                   return true;
                                 } 
                             }
                        }
                   }
           }   
}
template<class D,class T>
void mylink<D,T>::print(void)
{
    if(shead!=NULL)
      {
        spointer=shead;
        while(spointer!=NULL)
            {
               cout<<spointer->data<<endl;
               pointer=spointer->nextnode();
               if(pointer!=NULL)
                 {
                  cout<<spointer->data<<endl;
                  }
              while(pointer!=NULL)
                 { 

               cout<<"     "<<pointer->data<<"   "<<pointer->data<<endl;
                    pointer=pointer->nextnode();
                 } 
                   spointer=spointer->snextnode();
            }  
      }
}
template<class D,class T>
void mylink<D,T>::athead(void)
{
     spointer=shead;          
}
template<class D,class T>
snode<D,T> mylink<D,T>::gethead(void)
{
     return shead;
}
template<class D,class T>
void mylink<D,T>::display_QEdit_Text(QListWidget* e)
{
      e->clear();
	QString str_path;
    if(shead!=NULL)
      {
        spointer=shead;
        while(spointer!=NULL)
            {
               pointer=spointer->nextnode();
               if(pointer!=NULL)
                 {
                    str_path=QString::fromStdString(spointer->data);
		    e->addItem(str_path);
                  }
              while(pointer!=NULL)
                 {
               QString lineinfo; 
               QString file_path_num;
              lineinfo=QString::number(pointer->data.line_no)+QString(":   ")+QString::fromStdString((pointer->data.linecontext));
                 e->addItem(lineinfo);  
		 pointer=pointer->nextnode();
                 } 
                   spointer=spointer->snextnode();
               }
        }
}
template<class D,class T>  
void mylink<D,T>::mat_print(void)
{
    if(shead!=NULL)
      {
        spointer=shead;
        while(spointer!=NULL)
            {
             //  cout<<spointer->data<<endl;
               pointer=spointer->nextnode();
               if(pointer!=NULL)
                 {
                  cout<<spointer->data<<endl;
                  }
              while(pointer!=NULL)
                 {
                
               cout<<"     "<<pointer->data.line_no<<"   "<<pointer->data.linecontext<<endl;
                   pointer=pointer->nextnode();
                 } 
                   spointer=spointer->snextnode();
               }
        }
}


